home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / viewkit / VCal / WeekOverview.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.5 KB  |  530 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include "WeekOverview.h"
  19. #include "VCal.h"
  20. #include "Preferences.h"
  21. #include "TimeWeekdayEntry.h"
  22. #include "Info.h"
  23. #include "DayView.h"
  24. #include <Vk/VkMenuBar.h>
  25. #include <Vk/VkMenuItem.h>
  26. #include <Vk/VkHelpPane.h>
  27.  
  28. #include <Xm/Form.h>
  29. #include <Xm/DrawingA.h>
  30. #include <Xm/Label.h>
  31. #include <Xm/LabelG.h>
  32. #include <Xm/ToggleBG.h>
  33.  
  34. static int count;
  35. static Arg args[10];
  36.  
  37. /**********************************************************************/
  38.  
  39. WeekOverview::WeekOverview(VCal *o, const char *docName)
  40. : VkWindow(docName)
  41. {
  42.   owner = o;
  43.  
  44.   day = month = year = 0;
  45.   grid = NULL;
  46.   restricted = thePreferences->restricted();
  47.   timeInterval = thePreferences->gridLength();
  48.   subdivisions = thePreferences->apptSubdiv();
  49.   timeSlotSnap = thePreferences->snapInterval();
  50.   restricted = thePreferences->restricted();
  51.   restrictStart = 60*thePreferences->restrictStart();
  52.   restrictEnd = 60*thePreferences->restrictStop();
  53.   defaultLength = thePreferences->apptLength();
  54.   numEntries = 0;
  55.   sizeEntries = 16;
  56.   entries = (TimeWeekdayEntry **)
  57.     malloc(sizeEntries*sizeof(TimeWeekdayEntry *));
  58.   dirty = False;
  59.   troughGC = NULL;
  60.   headerArea = NULL;
  61. }
  62.  
  63. WeekOverview::~WeekOverview()
  64. {
  65.   clearData();
  66.   free(entries);
  67.   if (troughGC) {
  68.     XtReleaseGC(form, troughGC);
  69.   }
  70.   if (headerArea) {
  71.     XtAddCallback(headerArea, XmNexposeCallback,
  72.           WeekOverview::expose_check, (XtPointer) this);
  73.   }
  74. }
  75.  
  76. const char *
  77. WeekOverview::className()
  78. {
  79.   return "WeekOverview";
  80. }
  81.  
  82. /**********************************************************************/
  83.  
  84. void
  85. WeekOverview::selectWeek(int d, int m, int y)
  86. {
  87.   int weekday, each;
  88.   char str[256];
  89.   XmString xs;
  90.  
  91.   day = d;
  92.   month = m;
  93.   year = y;
  94.   if (visible() && !iconic()) {
  95.     if (owner->getDayView() &&
  96.     owner->getDayView()->visible()) {
  97.       weekday = computeWeekday(owner->getDayView()->day(),
  98.                    owner->getDayView()->month(),
  99.                    owner->getDayView()->year());
  100.       highlightWeekday(weekday);
  101.     } else {
  102.       highlightWeekday(0);
  103.     }
  104.     weekday = computeWeekday(d, m, y);
  105.     decrementDate(d, m, y, weekday-1, &day, &month, &year);
  106.     clearData();
  107.     for (each=0; each<DAYS_IN_WEEK; each++) {
  108.       augmentDate(day, month, year, each, &d, &m, &y);
  109.       addDateEntries(d, m, y, each+1);
  110.     }
  111.     scroll->reannotateScrollBar();
  112.  
  113.     strcpy(str, "Week of ");
  114.     formatDate(day, month, year, str+strlen(str));
  115.     strcat(str, " to ");
  116.     augmentDate(day, month, year, DAYS_IN_WEEK-1, &d, &m, &y);
  117.     formatDate(d, m, y, str+strlen(str));
  118.     xs = XmStringCreateSimple(str);
  119.     count = 0;
  120.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  121.     XtSetValues(weekLabel, args, count);
  122.     XmStringFree(xs);
  123.  
  124.     dirty = False;
  125.   } else {
  126.     dirty = True;
  127.   }
  128. }
  129.  
  130. /**********************************************************************/
  131.  
  132. Widget
  133. WeekOverview::setUpInterface(Widget parent)
  134. {
  135.   int each;
  136.   XmString xs;
  137.   char name[256];
  138.  
  139.   fileMenu();
  140.   if (menu()->helpPane()) {
  141.     menu()->helpPane()->setItemSensitivities(False, True, False, False,
  142.                          False);
  143.   }
  144.  
  145.   count = 0;
  146.   form = XmCreateForm(parent, "weekOverviewForm", args, count);
  147.  
  148.   scroll = new VkScroll("scroll", form);
  149.   VkAddCallbackMethod(VkScroll::scrollCallback, scroll, this,
  150.               WeekOverview::scrollProc, NULL);
  151.   scroll->setAnnotations();
  152.  
  153.   count = 0;
  154.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  155.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  156.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  157.   weekLabel = XmCreateLabelGadget(form, "weekLabel", args, count);
  158.   XtManageChild(weekLabel);
  159.  
  160.   count = 0;
  161.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  162.   XtSetArg(args[count], XmNtopWidget, weekLabel);  count++;
  163.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  164.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  165.   XtSetArg(args[count], XmNbackground, owner->normalColor());  count++;
  166.   headerArea = XmCreateDrawingArea(form, "headerArea", args, count);
  167.   XtManageChild(headerArea);
  168.   XtAddCallback(headerArea, XmNexposeCallback,
  169.         WeekOverview::expose_check, (XtPointer) this);
  170.  
  171.   for (each=0; each<DAYS_IN_WEEK; each++) {
  172.     sprintf(name, "%s", weekdayString(each+1));
  173.     xs = XmStringCreateSimple(name);
  174.     count = 0;
  175.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  176.     headerLabels[each] = XmCreateLabel(headerArea, "headerLabel", args, count);
  177.     XmStringFree(xs);
  178.     XtManageChild(headerLabels[each]);
  179.   }
  180.  
  181.   count = 0;
  182.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  183.   XtSetArg(args[count], XmNtopWidget, headerArea);  count++;
  184.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  185.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  186.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM);  count++;
  187.   XtSetValues(scroll->baseWidget(), args, count);
  188.  
  189.   if (restricted) {
  190.     grid = new TimeGrid("timeGrid", scroll->getClip(), False,
  191.             timeInterval, subdivisions,
  192.             restrictStart, restrictEnd-restrictStart);
  193.   } else {
  194.     grid = new TimeGrid("timeGrid", scroll->getClip(), False);
  195.   }
  196.   grid->setCallback(WeekOverview::grid_stub, (XtPointer) this);
  197.   count = 0;
  198.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_NONE);  count++;
  199.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_NONE);  count++;
  200.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  201.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  202.   XtSetValues(grid->baseWidget(), args, count);
  203.   scroll->setChild(grid->baseWidget());
  204.   grid->show();
  205.  
  206.   XtManageChild(form);
  207.   return form;
  208. }
  209.  
  210. void
  211. WeekOverview::handleWmDeleteMessage()
  212. {
  213.   doQuit();
  214. }
  215.  
  216. void
  217. WeekOverview::fileMenu()
  218. {
  219.   VkSubMenu* menu = addMenuPane("weekOverviewFileMenu");
  220.   VkMenuToggle *item;
  221.  
  222.   item = menu->addToggle("restrictedToggleMenuItem",
  223.              WeekOverview::restricted_menu,
  224.              (XtPointer) this);
  225.   item->setVisualState(thePreferences->restricted());
  226.   menu->addSeparator();
  227.   menu->addAction("weekOverviewQuitMenuItem",
  228.           WeekOverview::quit_menu,
  229.           (XtPointer) this);
  230. }
  231.  
  232. void
  233. WeekOverview::doQuit()
  234. {
  235.   hide();
  236. }
  237.  
  238. void
  239. WeekOverview::restrictedChanged(Boolean r)
  240. {
  241.   if (restricted != r) {
  242.     theApplication->busy();
  243.     restricted = r;
  244.     if (restricted) {
  245.       grid->changeDuration(restrictStart, restrictEnd-restrictStart);
  246.     } else {
  247.       grid->changeDuration(0, MINS_IN_DAY);
  248.     }
  249.     updateDisplay();
  250.     scroll->recomputeScrollBar();
  251.     theApplication->notBusy();
  252.   }  
  253. }
  254.  
  255. void
  256. WeekOverview::scrollProc(Widget, XtPointer, XtPointer call_data)
  257. {
  258.   VkScrollCallback *cb = (VkScrollCallback *) call_data;
  259.  
  260.   switch (cb->reason) {
  261.   case VS_initialExpose:
  262.     adjustGrid();
  263.     break;
  264.   case VS_resize:
  265. // Make the grid reconfigure first
  266.     grid->reconfig();
  267.     adjustGrid();
  268.     updateDisplay();
  269.     break;
  270.   case VS_troughPixmap:
  271.     drawTrough(cb);
  272. // Do nothing, no annotations in this view
  273.     break;
  274.   case VS_none:
  275.   default:
  276.     break;
  277.   }
  278. }
  279.  
  280. void
  281. WeekOverview::gridCallback(TimeGridCallback *cb)
  282. {
  283.   int each, d, m, y;
  284.   Position x;
  285.   Dimension width, borderWidth;
  286.   XEvent *event;
  287.  
  288.   switch (cb->reason) {
  289.   case TG_requestNew:
  290.     // Select a new day
  291.     if ((event = (XEvent *) cb->data) &&
  292.     event->type == ButtonPress) {
  293.       for (each=0; each<DAYS_IN_WEEK; each++) {
  294.     count = 0;
  295.     XtSetArg(args[count], XmNx, &x);  count++;
  296.     XtSetArg(args[count], XmNwidth, &width);  count++;
  297.     XtSetArg(args[count], XmNborderWidth, &borderWidth);  count++;
  298.     XtGetValues(headerLabels[each], args, count);
  299.     width += borderWidth;
  300.     if (event->xbutton.x >= x &&
  301.         event->xbutton.x < x+width) {
  302.       augmentDate(day, month, year, each, &d, &m, &y);
  303.       owner->selectDay(d, m, y);
  304.       break;
  305.     }
  306.       }
  307.     }
  308.     break;
  309.   case TG_deselect:
  310.     // Do nothing, this view is non-editable
  311.     break;
  312.   case TG_none:
  313.     break;
  314.   }
  315. }
  316.  
  317. void
  318. WeekOverview::adjustGrid()
  319. {
  320.   int each;
  321.   Position x, y;
  322.   Dimension width, height, borderWidth;
  323.  
  324.   count = 0;
  325.   XtSetArg(args[count], XmNincrement,
  326.        grid->getSlotHeight()*grid->getSubDiv());  count++;
  327.   XtSetValues(scroll->getScrollBar(), args, count);
  328.   for (each=0; each<DAYS_IN_WEEK; each++) {
  329.     if (grid->requestWeekdayPosition(restrictStart, 0, each+1,
  330.                      &x, &y, &width, &height)) {
  331.       count = 0;
  332.       XtSetArg(args[count], XmNborderWidth, &borderWidth);  count++;
  333.       XtGetValues(headerLabels[each], args, count);
  334.       count = 0;
  335.       XtSetArg(args[count], XmNx, x+borderWidth);  count++;
  336.       XtSetArg(args[count], XmNwidth, width-2*borderWidth);  count++;
  337.       XtSetValues(headerLabels[each], args, count);
  338.     }
  339.   }
  340.   for (each=0; each<numEntries; each++) {
  341.     if (entries[each]->reposition()) {
  342.       entries[each]->show();
  343.     } else {
  344.       entries[each]->hide();
  345.     }
  346.   }
  347. }
  348.  
  349. void
  350. WeekOverview::clearData()
  351. {
  352.   int each;
  353.  
  354.   for (each=0; each<numEntries; each++) {
  355.     delete entries[each];
  356.   }
  357.   numEntries = 0;
  358. }
  359.  
  360. void
  361. WeekOverview::addDateEntries(int day, int month, int year, int weekday)
  362. {
  363.   MemoryInfo *info;
  364.   Entry *entry;
  365.   RepeatingEntry *rentry;
  366.  
  367.   info = owner->findDateInfo(day, month, year);
  368.   if (info) {
  369.     info->rewind();
  370.     while (entry = info->nextEntry()) {
  371.       addEntry(entry, weekday);
  372.     }
  373.   }
  374.   rentry = owner->getRepeatingEntries();
  375.   while (rentry->next()) {
  376.     rentry = rentry->next();
  377.     if (rentry->repeatApplies(day, month, year)) {
  378.       addEntry(rentry, weekday);
  379.     }
  380.   }
  381. }
  382.  
  383. void
  384. WeekOverview::addEntry(Entry *entry, int weekday)
  385. {
  386.   if (numEntries == sizeEntries) {
  387.     sizeEntries = 2*sizeEntries;
  388.     entries = (TimeWeekdayEntry **) realloc(entries,
  389.             sizeEntries*sizeof(TimeWeekdayEntry *));
  390.   }
  391.   entries[numEntries] = new TimeWeekdayEntry("timeWeekdayEntry", grid,
  392.                          weekday);
  393.   entries[numEntries]->setCallback(WeekOverview::entry_stub, (XtPointer) this);
  394.   entries[numEntries]->setText(entry->text());
  395.   if (entries[numEntries]->setTimeInterval(entry->start(),
  396.                        entry->length())) {
  397.     entries[numEntries]->show();
  398.   }
  399.   numEntries++;
  400. }
  401.  
  402. void
  403. WeekOverview::entryCallback(Widget, TimeEntryCallback *cb)
  404. {
  405.   int time, d, m, y;
  406.  
  407.   if (cb->reason == TE_selected) {
  408.     time = cb->obj->start();
  409.     augmentDate(day, month, year, ((TimeWeekdayEntry *) cb->obj)->weekday()-1,
  410.         &d, &m, &y);
  411.     owner->selectDay(d, m, y);
  412.     if (owner->getDayView()) {
  413.       owner->getDayView()->scrollToTime(time);
  414.     }
  415.   }
  416. }
  417.  
  418. void
  419. WeekOverview::drawTrough(VkScrollCallback *cb)
  420. {
  421.   XGCValues gcv;
  422.   Pixel fg;
  423.   int each;
  424.  
  425.   if (troughGC == NULL) {
  426.     count = 0;
  427.     XtSetArg(args[count], XmNforeground, &fg);  count++;
  428.     XtGetValues(headerArea, args, count);
  429.     gcv.function = GXcopy;
  430.     gcv.foreground = fg;
  431.     gcv.background = owner->annotateColor();
  432.     gcv.stipple = owner->getTile();
  433.     gcv.fill_style = FillOpaqueStippled;
  434.     troughGC = XtGetGC(form,
  435.                GCFunction | GCForeground | GCBackground |
  436.                GCStipple | GCFillStyle,
  437.                &gcv);
  438.   }
  439.  
  440.   for (each=0; each<numEntries; each++) {
  441.     if (XtIsManaged(entries[each]->baseWidget())) {
  442.       annotateEntry(entries[each], cb->width, cb->height, cb->pixmap);
  443.     }
  444.   }
  445. }
  446.  
  447. void
  448. WeekOverview::annotateEntry(TimeEntry *entry, int width, int height,
  449.                 Pixmap pixmap)
  450. {
  451.   Position y;
  452.   Dimension height2;
  453.   int h;
  454.  
  455.   count = 0;
  456.   XtSetArg(args[count], XmNy, &y);  count++;
  457.   XtSetArg(args[count], XmNheight, &height2);  count++;
  458.   XtGetValues(entry->baseWidget(), args, count);
  459.   h = ((int) height2*height)/grid->getHeight();
  460.   if (h > 3) {
  461.     h -= 1;
  462.   }
  463.   XFillRectangle(XtDisplay(_baseWidget), pixmap, troughGC,
  464.          0, ((int) y*height)/grid->getHeight(),
  465.          width, h);
  466. }
  467.  
  468. void
  469. WeekOverview::highlightWeekday(int weekday)
  470. {
  471.   int each;
  472.  
  473.   for (each=0; each<DAYS_IN_WEEK; each++) {
  474.     count = 0;
  475.     if (each == weekday-1) {
  476.       XtSetArg(args[count], XmNborderColor, owner->foregroundColor()); count++;
  477.     } else {
  478.       XtSetArg(args[count], XmNborderColor, owner->normalColor());  count++;
  479.     }
  480.     XtSetValues(headerLabels[each], args, count);
  481.   }
  482. }
  483.  
  484. /************************************************************/
  485.  
  486. void
  487. WeekOverview::quit_menu(Widget, XtPointer client_data, XtPointer)
  488. {
  489.   WeekOverview *obj = (WeekOverview *) client_data;
  490.  
  491.   obj->doQuit();
  492. }
  493.  
  494. void
  495. WeekOverview::restricted_menu(Widget w, XtPointer client_data, XtPointer)
  496. {
  497.   WeekOverview *obj = (WeekOverview *) client_data;
  498.  
  499.   obj->restrictedChanged(XmToggleButtonGadgetGetState(w));
  500. }
  501.  
  502. void
  503. WeekOverview::grid_stub(Widget, XtPointer client_data, XtPointer call_data)
  504. {
  505.   WeekOverview *obj = (WeekOverview *) client_data;
  506.   TimeGridCallback *cb = (TimeGridCallback *) call_data;
  507.  
  508.   obj->gridCallback(cb);
  509. }
  510.  
  511. void
  512. WeekOverview::expose_check(Widget, XtPointer client_data, XtPointer)
  513. {
  514.   WeekOverview *obj = (WeekOverview *) client_data;
  515.  
  516.   if (obj->dirty) {
  517.     obj->updateDisplay();
  518.   }
  519. }
  520.  
  521. void
  522. WeekOverview::entry_stub(Widget w, XtPointer client_data, XtPointer call_data)
  523. {
  524.   WeekOverview *obj = (WeekOverview *) client_data;
  525.   TimeEntryCallback *cb = (TimeEntryCallback *) call_data;
  526.  
  527.   obj->entryCallback(w, cb);
  528. }
  529.  
  530.